#ifndef __QSPI_H__
#define __QSPI_H__

#include "xspi.h"		/* SPI device driver */

namespace SPIFlash {
	extern XSpi Spi;	// todo make private
	/*
	 * Definitions of the commands
	 */
	enum Command {
		COMMAND_PAGE_PROGRAM 	= 0x02, /* Page Program command */
		COMMAND_QUAD_WRITE 		= 0x32, /* Quad Input Fast Program */
		COMMAND_RANDOM_READ 	= 0x03, /* Random read command */
		COMMAND_DUAL_READ 		= 0x3B, /* Dual Output Fast Read */
		COMMAND_DUAL_IO_READ 	= 0xBB, /* Dual IO Fast Read */
		COMMAND_QUAD_READ 		= 0x6B, /* Quad Output Fast Read */
		COMMAND_QUAD_IO_READ 	= 0xEB, /* Quad IO Fast Read */
		COMMAND_WRITE_ENABLE 	= 0x06, /* Write Enable command */
		COMMAND_SECTOR_ERASE 	= 0xD8, /* Sector Erase command */
		COMMAND_BULK_ERASE 		= 0xC7, /* Bulk Erase command */
		COMMAND_STATUSREG_READ 	= 0x05  /* Status read command */
	};

	const uint32_t FLASH_PAGE_LENGTH		= 4096;
	const uint32_t FLASH_PAGE_LENGTH_BASE64	= ((4 * FLASH_PAGE_LENGTH / 3) + 3) & ~3;
	const uint32_t FLASH_PAGE_COUNT			= (128*1024*1024)/8/FLASH_PAGE_LENGTH;
	const uint32_t SECTOR_LENGTH			= 256;
	const uint32_t SECTORS_PER_PAGE			= FLASH_PAGE_LENGTH / SECTOR_LENGTH;

	int init();
	int writeEnable(XSpi *SpiPtr);
	int writePage(XSpi *SpiPtr, u32 pageNr, u8* data, u8 WriteCmd);
	int readPage(XSpi *SpiPtr, u32 pageNr, u8* data, u8 ReadCmd);
	int bulkErase(XSpi *SpiPtr);
	int sectorErase(XSpi *SpiPtr, u32 Addr);
	int getStatus(XSpi *SpiPtr);
	int quadEnable(XSpi *SpiPtr);
	int eraseWriteVerifyQuad(int pageNr, u8 *data);
}
#endif
